package cc.avatar.model;

import cc.avatar.model.rule.CarriagePR;

/**
 * 
 * 处理规则-为了回答事件(AccountingEvent)怎样形成帐务条目(Entry)这个问题。
 * 注意三个核心类：帐务事件、合同、处理规则之间的设计是怎样把"易变"的部分分离出来的。
 * 
 * 重要地：Rule是可以共享的，比如说数量乘以单位费率，可以用在很多业务事件中。
 */
public abstract class PostingRule {
	//注册固定的两个计费规则 - 运费 销售提成
    protected static PostingRule freightPostingRule = new CarriagePR();
    
	private AccountingEntry makeEntry(AccountingEvent evt, double amount) {
		return new AccountingEntry(evt.getStakeholder(), amount, evt.getWhenOccurred(),
				evt.getAtt1(), evt.getAtt2(), evt.getAtt3(), evt.getAtt4());
	}

	/**
	 * 处理过程就是为了创建帐务条目
	 */
	public AccountingEntry process(AccountingEvent evt) {
		return makeEntry(evt, calculateAmount(evt));
	}

	// 如何计费，虚方法，这是变化的核心部分，由子类来具体实现
	abstract protected double calculateAmount(AccountingEvent evt);
}
